package main

import (
	"fmt"
	"os"
	"reflect"
	"strconv"
)

func twoSum(nums []int, target int) []int {
	m := make(map[int]int)
	for i := 0; i < len(nums); i++ {
		another := target - nums[i]
		if _, ok := m[another]; ok {
			return []int{m[another], i}
		}
		m[nums[i]] = i
	}
	return nil
}

type ListNode struct {
	Val  int
	Next *ListNode
}

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
	head := &ListNode{Val: 0}
	n1, n2, carry, current := 0, 0, 0, head
	for l1 != nil || l2 != nil || carry != 0 {
		if l1 == nil {
			n1 = 0
		} else {
			n1 = l1.Val
			l1 = l1.Next
		}
		if l2 == nil {
			n2 = 0
		} else {
			n2 = l2.Val
			l2 = l2.Next
		}
		current.Next = &ListNode{Val: (n1 + n2 + carry) % 10}
		current = current.Next
		carry = (n1 + n2 + carry) / 10
	}
	return head.Next
}

type Sayer interface {
	say()
}
type Mover interface {
	move()
}

type Animal interface {
	Sayer
	Mover
}
type cat struct {
	name string
}

func (c cat) say() {
	fmt.Println("喵喵喵")
}

func (c cat) move() {
	fmt.Println("猫会动")
}

func show(a interface{}) {
	fmt.Printf("type:%T,value:%v", a, a)
}

func justifyType(x interface{}) {
	switch x.(type) {
	case string:
		fmt.Printf("x is string => %v\n", x)
	case int:
		fmt.Printf("x is int =>  %v\n", x)
	case bool:
		fmt.Printf("x is bool =>  %v\n", x)
	default:
		fmt.Println("not support type！")
	}
}
func doArgs() {
	if len(os.Args) > 0 {
		for i, arg := range os.Args {
			fmt.Printf("args[%d]=%v\n", i, arg)
		}
	}
}

func intAndStr() {
	s1 := "100"
	i1, err := strconv.Atoi(s1)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("type:%T,value:%#v\n", i1, i1)
	}
}

func Itoa() {
	i1 := 200
	s1 := strconv.Itoa(i1)
	fmt.Printf("type:%T,value:%#v\n", s1, s1)
}

func reflect_type(a interface{}) {
	t := reflect.TypeOf(a)
	fmt.Println("类型是：", t)
	kind := t.Kind()
	fmt.Println(kind)
	switch kind {
	case reflect.Float64:
		fmt.Println("a is float64")
	case reflect.String:
		fmt.Println("a is string")
	}
}

func reflect_value(a interface{}) {
	v := reflect.ValueOf(a)
	fmt.Println(v)
	kind := v.Kind()
	fmt.Println(kind)
	switch kind {
	case reflect.Float64:
		fmt.Println("a is ", v.Float())
	}
}

func reflect_set_value(a interface{}) {
	v := reflect.ValueOf(a)
	kind := v.Kind()
	switch kind {
	case reflect.Float64:
		v.SetFloat(6.9)
		//fmt.Println("a is ", v.Float())
	case reflect.Ptr:
		v.Elem().SetFloat(7.9)
		fmt.Println("case: ", v.Elem().Float())
		fmt.Println(v.Pointer())
	}
}

type User struct {
	Id   int
	Name string
	Age  int
}

func (u *User) ToString() string {
	return fmt.Sprintf("User:%p, %v", u, u)
}

func Poni(o interface{}) {
	t := reflect.TypeOf(o)
	fmt.Println("type is ", t)
	fmt.Println("字符串类型 ", t.Name())
	v := reflect.ValueOf(o)
	fmt.Println(v)
	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		fmt.Printf("%s : %v", f.Name, f.Type)
		val := v.Field(i).Interface()
		fmt.Println(" ,val : ", val)
	}
	fmt.Println("=================方法====================")
	for i := 0; i < t.NumMethod(); i++ {
		m := t.Method(i)
		fmt.Println(m.Name, m.Type)
	}
}

type Boy struct {
	User
	Addr string
}

func look() {
	boy := Boy{User{Name: "yzp", Id: 1, Age: 30}, "shanghai"}
	t := reflect.TypeOf(boy)
	fmt.Println(t)
	fmt.Printf("%#v\n", t.Field(0))
	fmt.Println("%#v\n", reflect.ValueOf(boy).Field(0))
}

func setValue(o interface{}) {
	v := reflect.ValueOf(o)
	v = v.Elem()
	f := v.FieldByName("Name")
	if f.Kind() == reflect.String {
		f.SetString("杨子平")
	}
}

func callMethod() {
	u := User{1, "zs", 20}
	v := reflect.ValueOf(u)
	m := v.MethodByName("Hello")
	args := []reflect.Value{reflect.ValueOf("杨子平")}
	m.Call(args)
}

type Student struct {
	Name string `json:"name1" db:"name2"`
}

func getTag() {
	var s Student
	v := reflect.ValueOf(&s)
	t := v.Type()
	field := t.Elem().Field(0)
	fmt.Println(field.Tag.Get("json"))
	fmt.Println(field.Tag.Get("db"))

}

func main() {
	getTag()
	//u := User{1, "zs", 20}
	//setValue(&u)
	//fmt.Println(u)
	//look()
	//var x float64 = 3.4
	//reflect_set_value(&x)
	//fmt.Println("main:", x)

	//justifyType(90)
	//var y interface{}
	//y = "pprof.cn"
	//v, ok := y.(string)
	//if ok {
	//	fmt.Println(v)
	//} else {
	//	fmt.Println("类型断言失败")
	//}

	//var studentInfo = make(map[string]interface{})
	//studentInfo["name"] = "Bob"
	//studentInfo["age"] = 18
	//studentInfo["married"] = false
	//fmt.Println(studentInfo)
	//
	//var x interface{}
	//
	//s := "pprof.cn"
	//x = s
	//fmt.Printf("type:%T,value:%v\n", x, x)
	//show(s)
	//var x Animal
	//x = cat{name: "花花"}
	//x.move()
	//x.say()

	//var nums = []int{2, 11, 15, 7}
	//target := 9
	//fmt.Println(twoSum(nums, target))
}
